package com.pagoda.nerp.trade.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pagoda.nerp.trade.common.ConstantDefine;
import com.pagoda.nerp.trade.common.PageListResult;
import com.pagoda.nerp.trade.common.enums.ErrorCodeMappingEnums;
import com.pagoda.nerp.trade.common.exception.BaseException;
import com.pagoda.nerp.trade.common.exception.UpdateException;
import com.pagoda.nerp.trade.common.wx.handler.WxMessageHandler;
import com.pagoda.nerp.trade.dao.*;
import com.pagoda.nerp.trade.entity.MdAccount;
import com.pagoda.nerp.trade.entity.MdVendor;
import com.pagoda.nerp.trade.entity.MdVendorAccount;
import com.pagoda.nerp.trade.entity.MdVendorCheck;
import com.pagoda.nerp.trade.service.MdVendorService;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

@Service
public class MdVendorServiceImpl implements MdVendorService {

	private static final Logger logger = LoggerFactory.getLogger(MdVendorServiceImpl.class);

	@Autowired
	private SysBillRuleDao sysBillRuleDao;

	@Autowired
	private MdVendorDao mdVendorDao;
	
	@Autowired
	private MdAccountDao mdAccountDao;

	@Autowired
	private MdVendorAccountDao mdVendorAccountDao;

	@Autowired
	private MdVendorCheckDao mdVendorCheckDao;
	
	public MdVendor selectByCondition(Integer accountId){
		return mdVendorDao.selectByCondition(accountId);
	}
	
	public int insert(MdVendor mdVendor){
		return mdVendorDao.insert(mdVendor);
	}
	
	@Transactional
	public Map<String, Object> register(String vendorName,String customerKind,String contacts,String phoneNumber,
			String verifyCode,String organizationCode,String cardNo,String openId) throws Exception {
		Map<String, Object> data = new HashMap<String, Object>();
		
		// 添加供应商
		MdVendor mdVendor = new MdVendor();
		int vendorId = sysBillRuleDao.generateId(ConstantDefine.BILLCODE_VENDOR_ID_V);
		mdVendor.setVerifyStatus(ConstantDefine.VENDOR_VERIFYSTATUS_INI);
		mdVendor.setContacts(contacts);
		mdVendor.setCustomerKind(customerKind);
		mdVendor.setVendorName(vendorName);
		mdVendor.setPhoneNumber(phoneNumber);
		mdVendor.setOrganizationCode(organizationCode);
		mdVendor.setCardNo(cardNo);
		mdVendor.setVendorId(vendorId);
		mdVendor.setVendorCode(sysBillRuleDao.generateCode(ConstantDefine.BILLCODE_VENDOR_CODE));
		mdVendor.setCustomerType("V");
		mdVendor.setVendorStatus("A");
		int resultCode = mdVendorDao.insert(mdVendor);
		if (resultCode < 0) {
			throw new Exception("vendor insert into db failed with mdVendor="+mdVendor);
		}

		// 添加供应商子账号
		MdAccount mdAccount = new MdAccount();
		mdAccount.setAccount(mdVendor.getPhoneNumber());
		mdAccount.setAccountType(ConstantDefine.ACCOUNT_TPYE_MAIN);
		mdAccount.setPasswdType("D");
		mdAccount.setName(mdVendor.getContacts());
		mdAccount.setIsBind(ConstantDefine.ACCOUNT_BLIANDWX_YES);
		mdAccount.setOpenid(openId);
		resultCode = mdAccountDao.insert(mdAccount);
		if (resultCode < 0) {
			throw new Exception("account insert into db failed with "+mdAccount);
		}

		// 添加供应商与子账号关系
		MdVendorAccount mdVendorAccount = new MdVendorAccount();
		mdVendorAccount.setAccountId(mdAccount.getAccountId());
		mdVendorAccount.setVendorId(vendorId);
		mdVendorAccount.setType(ConstantDefine.ACCOUNT_TPYE_MAIN);
		resultCode = mdVendorAccountDao.insert(mdVendorAccount);
		if (resultCode < 0) {
			throw new Exception("mdVendorAccount insert into db failed with "+mdVendorAccount);
		}
		
		data.put("vendorInfo", mdVendor);
		data.put("account", mdAccount);
		data.put("accountType", mdAccount.getAccountType());
		data.put("accountId", mdAccount.getAccountId());
		return data;
	}
	
	
	
	/**
	 * 获取供应商列表
	 * @param con 条件key
	 * @return
	 */
	@Override
	public PageListResult<MdVendor> listAllMdVendor(Map con) {
		int pageNo = con.get("pageNo") != null ? Integer.parseInt(con.get("pageNo").toString()) : 0;
		int pageSize = con.get("pageSize") != null ?  Integer.parseInt(con.get("pageSize").toString()) : 0;
		Page<MdVendor> pageInfo = PageHelper.startPage(pageNo, pageSize);
		List<MdVendor> listMdVendor = (List<MdVendor>) mdVendorDao.selectAllByConditon(con);
		return new PageListResult<MdVendor>(pageInfo,listMdVendor);
	}

	/**
	 * 获取供应商详情
	 * @param con 查询条件
	 * @return
	 */
	@Override
	public MdVendor findMdVendorByCon(Map con) {
		return mdVendorDao.selectOneByCondition(con);
	}

	@Override
	public int updateMdVendorByCon(Map con) throws UpdateException {
		return 0;
	}

	/**
	 * 供应商审核
	 * 逻辑：
	 * 1、每次审核需要对审核人、审核时间进行记录；
	 * 2、每次审核需要记录对应的流水
	 * 3、批量审核时同时需要对多个供应商进行流水状态的记录
	 * 4、每次审核都需要重新更新当前审核记录的最后一次更新ID值，lastCheckId
	 * 5、先执行流水记录，然后再执行数据的更新 - 使用批量插入的方式进行新增
	 * 6、@TODO 暂时使用单条插入并进入的方式，mybatis批量插入暂不支持单条失败的回滚，后续扩展
	 * 7、@TODO 批量更新需继续扩展
	 * @param con
	 * @return
	 * @throws UpdateException
	 */
	@Transactional
	@Override
	public int checkVendor(Map con) throws UpdateException {

		// 1、批量：解析重组每个供应商的ID及CODE进行处理
		String[] vendorIds = (String[]) con.get("vendorIds");
		String[] vendorCodes = (String[]) con.get("vendorCodes");

		// 查询判断当前状态是否为可审核状态 B 待审核 C 审核通过 D 审核驳回
		Map queryParams = new HashMap();
		queryParams.put("vendorIds", vendorIds);
		queryParams.put("verifyStatus","B");
		int count = mdVendorDao.selectCountByCondition(queryParams);
		if(count != vendorIds.length) {
			throw new BaseException(ErrorCodeMappingEnums.ERROR_EXCEPTION_VENDOR_STATUS);
		}

		for(int i = 0 ; i < vendorIds.length ; i++){
			// 记录供应商的信息 - 单次更新
			int vendorId = Integer.parseInt(vendorIds[i]);
			String vendorCode = vendorCodes[i];
			MdVendorCheck mdVendorCheck = new MdVendorCheck();
			mdVendorCheck.setVendorId(vendorId);
			mdVendorCheck.setVendorCode(vendorCode);
			mdVendorCheck.setCheckUser(con.get("checkUser").toString());
			mdVendorCheck.setCheckStatus(con.get("checkStatus").toString());
			mdVendorCheck.setCheckDesc(con.get("checkDesc").toString());

			int rowApp = this.mdVendorCheckDao.insert(mdVendorCheck);
			if(rowApp > 0){ // 更新成功
				con.put("lastCheckId", mdVendorCheck.getId());
				con.put("vendorId", vendorId);
				con.put("vendorCode", vendorCode);
				String checkStatus = con.get("checkStatus").toString();
				String verifyStatus = "";
				if(StringUtils.isNotEmpty(checkStatus)){
					if(checkStatus.equalsIgnoreCase("Y")){
						verifyStatus = "C";
					}
					if(checkStatus.equalsIgnoreCase("N")){
						verifyStatus = "D";
					}
				}
				con.put("verifyStatus", verifyStatus);
				con.remove("vendorIds");
				con.remove("vendorCodes");
			}
			int mdVendorRowApp = mdVendorDao.updateByCondition(con);
			if(mdVendorRowApp == 0){
				throw new UpdateException("更新供应商信息进行审核失败!!");
			}
		}

		// 判断审核状态 - 成功或失败需要进行消息通知 B 待审核 C 已通过 D 未通过
		sendMessageToWx(con,vendorIds);

		return 1;
	}

	/**
	 * 根据审核状态分别下发不通的通知信息
	 * 对供应商下所有子账户已绑定微信的账号进行信息推送
	 * 1、checkStatus = C , 下发成功通知(注册用户名、注册手机号码、审核日期、如有疑问请致电4001811212！)
	 * 2、checkStatus = D , 下发失败通知（由于{{@驳回原因}}，很遗憾您在百果园交易平台的注册信息未能通过审核。）
	 * @param params
	 */
	public void sendMessageToWx(Map<String,Object> params,String[] vendorIds){

		// 根据供应商查找子账户信息（供应商名称、子账户、openid、时间）
		Object checkStatus = params.get("verifyStatus");
		Object checkDesc = params.get("checkDesc");
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String datetime = simpleDateFormat.format(new Date());

		// 查询当前所有供应商对应的子账户信息 - （）
		Map<String,Object> queryMap = new HashMap<String,Object>();
		queryMap.put("vendorIds", vendorIds);
		// 对MdAccount 进行字段冗余
		List<MdAccount> mdAccountList = mdAccountDao.selectAllByConditon(queryMap);
		if(null == mdAccountList || mdAccountList.size() == 0){
			logger.info("Service 未查询到供应商相关信息，不进行消息推送动作!{}",vendorIds);
		}
		for(MdAccount mdAccount : mdAccountList){
			if(!StringUtils.isNotEmpty(mdAccount.getOpenid())){
				continue;
			}
			// 发送成功消息
			if(null != checkStatus && checkStatus.toString().toUpperCase().equals("C")){
				WxMessageHandler.sendRegisterNotifyMsg("恭喜您在百果园交易平台的注册信息通过审核!", mdAccount.getName(), mdAccount.getAccount(), datetime, "", mdAccount.getOpenid());
			}else{
				String description = "由于"+checkDesc.toString()+"，很遗憾您在百果园交易平台的注册信息未能通过审核。";
				WxMessageHandler.sendRegisterNotifyMsg(description, mdAccount.getName(), mdAccount.getAccount(), datetime, "", mdAccount.getOpenid());
			}
		}

	}

	public int updateById(MdVendor mdVendor){
		return mdVendorDao.updateById(mdVendor);
	}
}

